#ifndef BLOB_DETECTOR_H
#define BLOB_DETECTOR_H

/********** Library Includes **************************************************/

#include <opencv/cv.h>
#include <opencv/highgui.h>

/********** Classes ***********************************************************/

class BlobDetector {
public:
	enum Color {
		NO_COLOR,
		COLOR_RED,
		COLOR_GREEN,
		COLOR_BLUE
	};
	
	enum BlobCategory {
		UNCATEGORIZED,
		ROBOT_LEFT,
		ROBOT_RIGHT,
		FRUIT
	};
	
	struct ColorThresholds {
		int hueL;
		int hueH;
		int satL;
		int satH;
		int valL;
		int valH;
	};

	struct Blob {
		cv::Point center;
		int size;
		Color color;
		BlobCategory category;
	};
	
	BlobDetector(const ColorThresholds &red, int redBlur,
		const ColorThresholds &green, int greenBlur, 
		const ColorThresholds &blue, int blueBlur, int camera);
	
	/**
	 * Uses the set thresholds to identify all blobs in the given image.
	 */
	std::vector<Blob> findBlobs(const std::string &filename = std::string());
	
	/**
	 * Filters the given blobs for the largest green and the two largest red.
	 */
	std::vector<Blob> filterForLargest(const std::vector<Blob> &allBlobs) const;
	
	/**
	 * Categorizes each of the given blobs into one of the three blob categories
	 * given by the enum BlobCategory.
	 */
	std::map<BlobCategory, Blob> categorize(const std::vector<Blob> &largest) const;
	
	void showDebug(const std::map<BlobCategory, Blob> &) const;

protected:
	void applyThresholds(const cv::Mat &src, cv::Mat &dst,
		const ColorThresholds &) const;
	
	std::vector<Blob> findBlobs(const cv::Mat& rgbImage, Color color,
		const ColorThresholds &thresholds);

private:
	std::map<Color, ColorThresholds> m_thresholds;
	int m_cameraCode;
	cv::SimpleBlobDetector m_sbd;
	std::map<Color, int> m_blurSizes;
	cv::Mat m_image;
};

double euclidean(cv::Point p1, cv::Point p2);
#endif
